package org.dt.common.sftp;

import com.jcraft.jsch.*;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.pool2.KeyedPooledObjectFactory;
import org.apache.commons.pool2.PooledObject;
import org.apache.commons.pool2.impl.DefaultPooledObject;

import java.util.Properties;

@Slf4j
public class SftpClientFactory implements KeyedPooledObjectFactory<SftpClientKey, ChannelSftp> {

    @Override
    public PooledObject<ChannelSftp> makeObject(SftpClientKey key) throws Exception {
        JSch    jsch       = new JSch();
        Session sshSession = jsch.getSession(key.getUsername(), key.getHost(), key.getPort());
        sshSession.setPassword(key.getPassword());

        Properties sshConfig = new Properties();
        sshConfig.put("StrictHostKeyChecking", "no");
        sshSession.setConfig(sshConfig);
        sshSession.connect();

        Channel channel = sshSession.openChannel("sftp");
        channel.connect();
        log.info("connet to sftp {} {} {}", key.getHost(), key.getPort(), key.getUsername());

        return new DefaultPooledObject<>((ChannelSftp) channel);
    }

    @Override
    public void destroyObject(SftpClientKey key, PooledObject<ChannelSftp> p) throws Exception {
        ChannelSftp sftp = p.getObject();
        if (sftp != null) {
            if (sftp.isConnected()) {
                Session session = sftp.getSession();
                sftp.disconnect();
                session.disconnect();

                log.info("disconnect from {} {} {}", key.getHost(), key.getPort(), key.getUsername());
            } else if (sftp.isClosed()) {
                log.info("sftp is closed already. {} {} {}", key.getHost(), key.getPort(), key.getUsername());
            }
        }
    }

    @Override
    public boolean validateObject(SftpClientKey key, PooledObject<ChannelSftp> p) {
        try {
            p.getObject().ls("/");
            return true;

        } catch (SftpException e) {
            log.info("current sftp is not valid of {} {} {}", key.getHost(), key.getPort(), key.getUsername());
            return false;
        }
    }

    @Override
    public void activateObject(SftpClientKey key, PooledObject<ChannelSftp> p) throws Exception {
        // do nothing
    }

    @Override
    public void passivateObject(SftpClientKey key, PooledObject<ChannelSftp> p) throws Exception {
        // do nothing
    }

}
